package com.hmall.item.controller;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hmall.common.domain.PageDTO;
import com.hmall.item.domain.dto.ItemDTO;
import com.hmall.item.domain.po.Item;
import com.hmall.item.domain.po.ItemDoc;
import com.hmall.item.domain.query.ItemPageQuery;
import com.hmall.item.service.IItemService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.apache.http.HttpHost;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Api(tags = "搜索相关接口")
@RestController
@RequestMapping("/search")
@RequiredArgsConstructor
public class SearchController {

    private final IItemService itemService;

    private final RestHighLevelClient client;



    @ApiOperation("搜索商品")
    @GetMapping("/list")
    public PageDTO<ItemDTO> search(ItemPageQuery query) throws IOException {

        //准备Request对象
        SearchRequest request = new SearchRequest("items");

        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();

        //关键字搜索
        if (StrUtil.isNotBlank(query.getKey())){
            boolQuery.must(QueryBuilders.matchQuery("name",query.getKey()));
        }
        //分类过滤
        if (StrUtil.isNotBlank(query.getCategory())){
            boolQuery.filter(QueryBuilders.termQuery("category",query.getCategory()));
        }
        //品牌过滤
        if (StrUtil.isNotBlank(query.getBrand())){
            boolQuery.filter(QueryBuilders.termQuery("brand",query.getBrand()));
        }
        //价格最大值过滤
        if (query.getMaxPrice()!=null && query.getMaxPrice()>0){
            boolQuery.filter(QueryBuilders.rangeQuery("price").lte(query.getMaxPrice()));
        }
        //价格最小值过滤
        if (query.getMinPrice()!=null && query.getMinPrice()>0){
            boolQuery.filter(QueryBuilders.rangeQuery("price").gte(query.getMinPrice()));
        }

        request.source().query(boolQuery);
        //分页
        request.source().from((query.getPageNo()-1)*query.getPageSize()).size(query.getPageSize());
        //排序
        if (StrUtil.isNotBlank(query.getSortBy())){
            request.source().sort(query.getSortBy(),query.getIsAsc()? SortOrder.ASC:SortOrder.DESC);
        }else {
            request.source().sort("updateTime",query.getIsAsc()?SortOrder.ASC:SortOrder.DESC);
        }
        //发送请求
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        PageDTO<ItemDTO> result = parseResponseResult(response,query);

        // 分页查询
//        Page<Item> result = itemService.lambdaQuery()
//                .like(StrUtil.isNotBlank(query.getKey()), Item::getName, query.getKey())
//                .eq(StrUtil.isNotBlank(query.getBrand()), Item::getBrand, query.getBrand())
//                .eq(StrUtil.isNotBlank(query.getCategory()), Item::getCategory, query.getCategory())
//                .eq(Item::getStatus, 1)
//                .between(query.getMaxPrice() != null, Item::getPrice, query.getMinPrice(), query.getMaxPrice())
//                .page(query.toMpPage("update_time", false));
        // 封装并返回
        return result;
    }

    private PageDTO<ItemDTO> parseResponseResult(SearchResponse response, ItemPageQuery query) {

        SearchHits searchHits = response.getHits();

        //总条数
        long total = searchHits.getTotalHits().value;

        SearchHit[] hits = searchHits.getHits();

        List<ItemDoc> itemDocList = Stream.of(hits)
                .map(
                        hit -> {
                            //获取source结果
                            String json = hit.getSourceAsString();
                            //转成ItemDoc
                            ItemDoc doc = JSONUtil.toBean(json, ItemDoc.class);

                            return doc;

                        }
                ).toList();

        //转成ItemDto集合
        List<ItemDTO> itemDTOS = BeanUtil.copyToList(itemDocList, ItemDTO.class);

        long pageSize = query.getPageSize().longValue();
        //返回结果
        return new PageDTO<>(total,pageSize,itemDTOS);

    }

}
